package com.hnchances.grade.controller;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hnchances.grade.common.group.AddGroup;
import com.hnchances.grade.common.group.UpdateGroup;
import com.hnchances.grade.common.utils.JWTUtils;
import com.hnchances.grade.common.utils.JedisUtils;
import com.hnchances.grade.common.utils.R;
import com.hnchances.grade.common.valid.PhoneNumberValid;
import com.hnchances.grade.dto.LoginDto;
import com.hnchances.grade.entity.StudentEntity;
import com.hnchances.grade.entity.UserEntity;
import com.hnchances.grade.service.StudentService;
import com.hnchances.grade.service.UserService;
import com.hnchances.grade.vo.JWTTokenVo;
import com.hnchances.grade.vo.RegisterVo;
import com.hnchances.grade.vo.UpdateUserVo;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import redis.clients.jedis.Jedis;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Random;


/**
 * @author lpj
 * @email ${email}
 * @date 2022-08-27 15:10:23
 */
@Slf4j
@RestController
@RequestMapping("grade/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private JedisUtils jedisUtils;
    @Autowired
    private StudentService studentService;

    /**
     * //TODO 实现真正的短信验证
     * 发送验证码
     */
    @ApiOperation(value = "获取验证码",notes = "阿里云短信验证签名未申请成功，所以先默认验证码为666666，有效时间5分钟")
    @GetMapping("/verify/{phoneNumber}")
    public R verify(@PhoneNumberValid @PathVariable("phoneNumber") String phoneNumber) {
        //生成随机验证码并存进去redis中
        Random random = new Random();
        String code = "";
        for (int i = 0; i < 6; i++) {
            int x = random.nextInt(10);
            code += x;
        }
        code = "666666";
        Jedis jedis = jedisUtils.getJedis();
        jedis.set("" + phoneNumber, code);
        jedis.expire("" + phoneNumber, 5 * 60);
        return R.ok().put("验证码",code);
    }

    /**
     * 列表
     * 前端测试使用：通过是否携带token鉴权
     *
     */
    @PostMapping("/userinfo")
    @ApiOperation(value = "拉取用户信息",notes = "前端人员测试使用，需要携带token")
    //@RequiresPermissions("grade:user:list")
    public R list(@RequestBody JWTTokenVo jwtTokenVo) {
        String verifyToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NjIyODQyMTIsInVzZXJuYW1lIjoi5byg5LiJNjY2In0.0qKhOzLMuudysxe0byiLJMxcM6IhW_9T76cB04HAQdw";
        String token = jwtTokenVo.getToken();
        log.info(token);
        if (token == null) {
            return R.error("权限不足");
        }
        if (!token.equals(verifyToken)) {
            return R.error("token错误");
        }
        List<UserEntity> list = userService.listWithoutPassword();
        return R.ok().put("data", list);
    }


    /**
     * 信息
     */
    @ApiOperation(value="根据id查询信息",notes="url中携带参数")
    @GetMapping(value = "/info/{id}")
    //@RequiresPermissions("grade:user:info")
    public R info(@PathVariable("id") @Validated Long id) {
        UserEntity user = userService.getById(id);

        return R.ok().put("user", user);
    }

    /**
     * 注册用户
     * 学生可根据身份证关联学生成员表的表字段学生ID，
     * 如班级无此人，不予以注册。老师关联班级ID、课程ID。
     * 注册采用短信验证的方式，使用阿里云短信验证（自行注册获取）。
     * 验证码请使用redis管理。验证机制，业务逻辑属于需求分析与业务需求内容
     */
    @PostMapping("/register")
    @ApiOperation(value = "用户注册")
    //@RequiresPermissions("grade:user:save")
    public R save(@Validated(AddGroup.class) @RequestBody RegisterVo registerVo) throws Exception {
        //进行验证码校验
        Integer verifyCode = registerVo.getVerifyCode();
        Jedis jedis = jedisUtils.getJedis();
        String s = jedis.get("" + registerVo.getPhone());
        if (!s.equals(verifyCode.toString()) || StringUtils.isEmpty(s)) {
            return R.error("验证码失效或验证码不正确，请重新输入验证码！");
        }
        //进行学生验证
        String idcard = registerVo.getIdcard();
        System.out.println(idcard);
        StudentEntity one = studentService.getOne(new QueryWrapper<StudentEntity>().eq("idcard", idcard));
        System.out.println(one.toString());
        if (one == null) {
            return R.error("当前学生不存在，请检查身份证号是否正确");
        }
        //将classid 还有studentid传给中间数据
        if (registerVo.getIdentity() == 0) {
            registerVo.setStudentId(one.getId());
        } else if (registerVo.getIdentity() == 1) {
            registerVo.setClassId(one.getClassId());
        }
        userService.registe(registerVo);
        return R.ok();
    }

    /**
     * 修改
     * 有鉴权：只有管理员可以进行修改
     */
    @RequiresRoles("管理员")
    @PostMapping("/update")
    @ApiOperation( value = "管理员进行信息修改",notes = "只有管理员可以修改用户的信息")
    //@RequiresPermissions("grade:user:update")
    public R update(@Validated({UpdateGroup.class}) @RequestBody UpdateUserVo updateUserVo, @RequestHeader("Authorization") String token) {
        //修改默认修改的信息aop
        R r = userService.updateByIdDetail(updateUserVo);
        return r;
    }

    /**
     * 删除
     * 权限：只有和管理员老师可以删除本班级user表中的用户
     */
    @RequiresRoles("老师")
    @RequestMapping(value = "/del",method = {RequestMethod.POST})
    @ApiOperation(value="删除本班级学生的用户信息",notes="只需传入id即可，采用学生类接收body参数")
    // @RequiresPermissions("grade:user:delete")
    public R delete(@RequestBody StudentEntity studentEntity, @RequestHeader("Authorization") String token) {
        Integer id = studentEntity.getId();
        R r = userService.removeByIdConditions(id, token);
        return r;
    }

    /**
     * 登陆
     *
     * @param loginDto
     * @param response
     * @return
     */
    @PostMapping("/login")
    @ApiOperation(value = "登陆",notes = "会把token返回给响应头")
    public R login(@RequestBody LoginDto loginDto, HttpServletResponse response) {
        //根据用户名去查用户
        String userName = loginDto.getUserName();
        UserEntity user = userService.getOne(
                new QueryWrapper<UserEntity>().eq("userName", userName));
        if (user == null) {
            return R.error("用户不存在");
        }
        if (!user.getPassWord().equals(SecureUtil.md5(loginDto.getPassWord()))) {
            return R.error("密码不正确");
        }
        //生成Jwt，返回响应头给前端
        String jwt = JWTUtils.sign(loginDto.getUserName(), loginDto.getPassWord());
        response.setHeader("Authorization", jwt);
        return R.ok().put("data", "登陆成功，返回jwt");
    }
}
